#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctime>


#include <stdlib.h>
#include <string.h>

bool prefixComp(int prefixLen, char* str1, char* str2) {
	for (int i=0; i<prefixLen; i++) {
		if (str1[i] == str2[i]) continue;
		return false;
	}
	return true;
}

bool handleArg( char* arg, bool* lowresPtr, int* timePtr, int* camNumPtr) {
	
	char* camString = "--cam=n";
	char* lowresString = "--lowres";
	char* timeString = "--time=t";
	
	int camStringLen = strlen(camString);
	int timeStringLen = strlen(camString);
	
	int argLen = strlen(arg);
	
	if ( strcmp(arg,lowresString)==0 ) { //strcmp returns 0 for true!
		*lowresPtr = true;
		return true;
	} else if ( argLen >= camStringLen && prefixComp(camStringLen-1,arg,camString) )  {
		*camNumPtr = atoi( &(arg[camStringLen-1]) );
		return true;
	} else if ( argLen >= timeStringLen && prefixComp(timeStringLen-1,arg,timeString) )  {
		*timePtr = atoi( &(arg[timeStringLen-1]) );
		return true;
	}
	
	return false;
}

int main( int argc, char** argv ) {
//	Usage:
//	cameraDisplayAndRecord_timed.out [--lowres, --cam=n, --time=t] <output filename>
//  where 0<t<100 (unit of t is seconds)
	
	
	bool lowres = false;
	int recordingTimeSeconds = 20;
	int camNum = 0;
	
	for (int i=1; i<argc; i++) {
		if( !handleArg(argv[i],&lowres,&recordingTimeSeconds,&camNum) && i != (argc-1) ) {
			return -1; // there must be exactly one argument left: the file name
		}
	}
	
	char* windowName = "Camera Recorder";
	cvNamedWindow( windowName, CV_WINDOW_AUTOSIZE );

	CvCapture* capture = cvCaptureFromCAM(camNum);
	//-1: dialog in Windows
	if (!capture){
        return -1;
    }
	
	
	int captureWidth = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH);
	int captureHeight = (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT); 
	
	if (lowres) {
		captureWidth = 640;
		captureHeight = 480;
		cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH, captureWidth);
		cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, captureHeight);
		//Hack! cvGetCaptureProperty does not seem to give correct value after cvSetCaptureProperty call
	}
	
	
	
	IplImage* frame;
	
	double fps = cvGetCaptureProperty (
									   capture,
									   CV_CAP_PROP_FPS
									   );
	//problem with fps for camera!
	
	//hack? //appears about right on Mac desktop

	
	if (lowres) {
		fps = 19;
	} else {
		fps = 13;
	}
	
	printf("fps=%d\n",(int)fps);
	
	int frameWaitTime_ms = int ( 1000 / fps ) ;
	
	printf("milliseconds per frame =%d\n", frameWaitTime_ms);
	
    CvSize size = cvSize(
						 captureWidth,
						 captureHeight
						 );
    
    printf("frame (w, h) = (%d, %d)\n",size.width,size.height);
#ifndef NOWRITE
	CvVideoWriter* writer = cvCreateVideoWriter(  // On linux Will only work if you've installed ffmpeg development files correctly, 
												argv[argc-1],                               // otherwise segmentation fault.  Windows probably better.
												//CV_FOURCC('D', 'I', 'B', ' '), //BROKEN!
												CV_FOURCC('I', '4', '2', '0'),
												//0, // apparently works on Windows, but here? OSX : it seems to default to I420
												//CV_FOURCC('F', 'L', 'V', '1'),
												//CV_FOURCC('D','X','5','0'),    
												fps,
												size
												);
#endif
	
	
	IplImage* mod_frame = cvCreateImage(
										 size,
										 IPL_DEPTH_8U,
										 3
										 );
	
	
	printf("PRESS ANY KEY TO START RECORDING IN 3 SEC\n");
	cvWaitKey(0);
	printf("3...\n");
	cvWaitKey(1000);
	printf("2...\n");
	cvWaitKey(1000);
	printf("1...\n");
	cvWaitKey(1000);
	printf("STARTING\n");
	
	
	
	int frameCount = 0;
	time_t startTime;

	int elapsedTime = 0;
	startTime = time (NULL);
	
	while(1) {
		frameCount++;
		frame = cvQueryFrame( capture );
		if( !frame ) break;
		cvConvertImage(   //We never make use of this gray image
					   frame,
					   mod_frame,
					   0
					   );
		cvShowImage( windowName, mod_frame );
#ifndef NOWRITE
		cvWriteToAVI( writer, mod_frame );
#endif
		elapsedTime = time(NULL) - startTime;
		if( elapsedTime >= recordingTimeSeconds ) break;
		
		char c = cvWaitKey(33);
		if( c != -1 ) break;
	}
	
	int avgFPS;
	
	if (elapsedTime != 0) {
		avgFPS = frameCount / elapsedTime;
	} else {
		avgFPS = -1;
	}
	
	printf("Avg fps =%d\n", avgFPS);
	
	
#ifndef NOWRITE
    cvReleaseVideoWriter( &writer );
#endif
	cvReleaseCapture( &capture );
	cvDestroyWindow( windowName );
}
